module(..., package.seeall)

require "utils.oop"
require "utils.misc"

import("glutton.utils.named", "Named")

----------------------------------------------------------------------------------------------------
Stat = class("Stat", Named)

function Stat.__init(self, name, initial_value)
    Named.__init(self, name)
    self.base = StatValue(self, "base", initial_value)
    self.curr = StatValue(self, "curr", initial_value)
end

function Stat.__info(self)
    return ("%s[%s]"):format(self.curr.value, self.base.value)
end

function Stat.add_bonus(self, bonus)
    bonus:apply_to(self)
end

function Stat.remove_bonus(self, bonus)
    bonus:remove_from(self)
end

function Stat.update(self)
    for _, stat_value in ipairs{self.base, self.current} do
        for bonus, _ in pairs(stat_value.contrib) do
            bonus:update(self)
        end
    end
end

----------------------------------------------------------------------------------------------------
StatValue = class("StatValue", Named)

function StatValue.__init(self, stat, name, initial_value)
    Named.__init(self, stat.name .. "." .. name)
    self.stat = stat
    self.value = initial_value
    self.contrib = {}
end

function StatValue.__info(self)
    return self.value
end

function StatValue.set_contrib(self, bonus, value)
    self.value = self.value + value - (self.contrib[bonus] or 0)
    self.contrib[bonus] = value
    self.stat:update()
end

function StatValue.del_contrib(self, bonus)
    if self.contrib[bonus] ~= nil then
        self.value = self.value - self.contrib[bonus]
        self.contrib[bonus] = nil
        self.stat:update()
    end
end
